
;
(function($) {
    $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',   'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'], function(i, attr) {
        $.fx.step[attr] = function(fx) {
            if (!fx.colorInit) {
                fx.start = getColor(fx.elem, attr);
                fx.end = getRGB(fx.end);
                fx.colorInit = true;
            }

            fx.elem.style[attr] = 'rgb(' +
                Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
                Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
                Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
        };
    });
    function getRGB(color) {
        var result;


        if (color && color.constructor == Array && color.length == 3)
            return color;


        if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
            return [parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10)];


        if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
            return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55];


        if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
            return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];


        if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
            return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)];


        if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
            return colors['transparent'];


        return colors[$.trim(color).toLowerCase()];
    }

    function getColor(elem, attr) {
        var color;

        do
        {
            color = $.curCSS(elem, attr);


            if (color != '' && color != 'transparent' || $.nodeName(elem, "body"))
                break;

            attr = "backgroundColor";
        }
        while (elem = elem.parentNode);

        return getRGB(color);
    }

    var borderRadiusStyle = $("<div />")[0].style;
    var borderRadiusKey = "borderRadius";
    if (borderRadiusStyle.borderRadius !== undefined) {
        borderRadiusKey = "borderRadius";
    }
    else
    if (borderRadiusStyle.WebkitBorderRadius !== undefined) {
        borderRadiusKey = "WebkitBorderRadius";
    }
    else
    if (borderRadiusStyle.MozBorderRadius !== undefined) {
        borderRadiusKey = "MozBorderRadius";
    }
    $.extend($.fx.step, {
        backgroundPosition: function(fx) {
            if (fx.state === 0 && typeof fx.end == 'string') {
                if ($.browser.msie) {
                    var start = $.curCSS(fx.elem, 'backgroundPositionX') + " " + $.curCSS(fx.elem, 'backgroundPositionY');
                }
                else {
                    var start = $.curCSS(fx.elem, 'backgroundPosition');
                }
                start = toArray(start);
                fx.start = [start[0],start[2]];
                var end = toArray(fx.end);
                fx.end = [end[0],end[2]];
                fx.unit = [end[1],end[3]];
            }
            var nowPosX = [];
            nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
            nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
            fx.elem.style.backgroundPosition = nowPosX[0] + ' ' + nowPosX[1];

            function toArray(strg) {
                strg = strg.replace(/left|top/g, '0px');
                strg = strg.replace(/right|bottom/g, '100%');
                strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g, "$1px$2");
                var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
                return [parseFloat(res[1], 10),res[2],parseFloat(res[3], 10),res[4]];
            }

        },
        borderRadius : function(fx) {
            fx.elem.style[borderRadiusKey] = fx.pos * (fx.end - fx.start) + "px";
        }
    });
})(jQuery);